home *** CD-ROM | disk | FTP | other *** search
- /*
- **
- ** $Id: arexx.c,v 1.1 1995/10/07 02:48:56 amiga Exp $
- ** $Revision: 1.1 $
- **
- ** $Filename: answeringmachine/arexx.c $
- ** $Author: amiga $
- ** $Date: 1995/10/07 02:48:56 $
- ** $Portability: AMIGADOS $
- **
- ** ARexx interface
- **
- ** COPYRIGHT (C) 1991, 1992 BY CHRISTIAN A. WEBER, ZUERICH.
- ** COPYRIGHT (C) 1992-1995 BY RELOG AG, ZUERICH. ALL RIGHTS RESERVED.
- ** NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, OR TRANSMITTED
- ** IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN PERMISSION
- ** OF RELOG AG.
- **
- */
-
- #include "os.h"
-
- #include <proto/exec.h>
- #include <clib/rexxsyslib_protos.h>
- #include <pragmas/rexxsyslib_pragmas.h>
- #include <proto/dos.h>
- #include <proto/intuition.h>
- #include <proto/utility.h>
-
- #include <string.h>
- #include <stdio.h>
-
- #define _AREXX
- #include "arexx.h"
-
- #include "am.h"
-
- #define MYREXXSUFFIX "amrx"
-
-
- static struct Library *RexxSysBase;
-
-
- /****************************************************************************
- ** ASCII String holen, Anführungszeichen interpretieren.
- ** Der Char*-Zeiger wird auf den Text nach dem String gesetzt.
- ** Gibt FALSE zurück, wenn kein Argument mehr vorhanden ist.
- */
-
- BOOL ARexx_GetString( char **strptr, char *dest, int destsize )
- {
- char *s = *strptr;
- BOOL result = FALSE;
-
- /*
- ** Führende Spaces überlesen
- */
- while (*s == ' ')
- s++;
-
-
- /*
- ** Text kopieren
- */
- if (*s == '"') /* Anführungszeichen --> plain copy */
- {
- s++;
- while (*s != '\0')
- {
- result = TRUE;
- if (*s == '\\') /* Escape-Sequenz */
- {
- s++;
- if (*s == '\0')
- break;
-
- switch (*s)
- {
- case 'n':
- if (destsize > 0)
- {
- *dest++ = '\n';
- destsize--;
- }
- break;
-
- default:
- if (destsize > 0)
- {
- *dest++ = *s;
- destsize--;
- }
- break;
- }
- s++;
- }
- else if (*s == '"')
- {
- s++;
- break;
- }
- else
- {
- if (destsize > 0)
- {
- *dest++ = *s;
- destsize--;
- }
- s++;
- }
- }
- }
- else /* Keine Anführungszeichen --> bis Space */
- {
- while (*s != '\0')
- {
- result = TRUE;
- if (*s == '\\') /* Escape-Sequenz */
- {
- s++;
- if (*s == '\0')
- break;
-
- switch (*s)
- {
- case 'n':
- if (destsize > 0)
- {
- *dest++ = '\n';
- destsize--;
- }
- break;
-
- default:
- if (destsize > 0)
- {
- *dest++ = *s;
- destsize--;
- }
- break;
- }
- s++;
- }
- else if(*s == ' ')
- {
- break;
- }
- else
- {
- if (destsize > 0)
- {
- *dest++ = *s;
- destsize--;
- }
- s++;
- }
- }
- }
- *dest = '\0';
-
- /*
- ** Spaces am Schluss überlesen
- */
- while (*s == ' ')
- s++;
-
- *strptr = s;
-
- return result;
- }
-
-
- /****************************************************************************
- ** ASCII nach Integer wandeln, Nachkommastellen werden unterdrückt.
- ** Der Char*-Zeiger wird auf den Text nach der Zahl gesetzt.
- ** Gibt FALSE zurück, wenn keine Zahl erkannt wurde.
- */
-
- BOOL ARexx_GetInteger( char **strptr, S32 *pInt )
- {
- char *s = *strptr;
- S32 zahl = 0;
- S8 sign = 1;
- BOOL result = FALSE;
-
- while (*s == ' ')
- s++;
-
- if (*s == '-')
- {
- sign = -1;
- s++;
- }
- else if(*s == '+')
- s++;
-
- while ((*s >= '0') && (*s <= '9'))
- {
- zahl = zahl * 10 + (*s++ - '0');
- result = TRUE;
- }
-
- while (*s == ' ')
- s++;
-
- *strptr = s;
- *pInt = (sign > 0) ? zahl : -zahl;
-
- return result;
- }
-
-
- /****************************************************************************
- ** Ein Rexx-Kommando auswerten, geht auch wenn ARexx NICHT läuft
- */
-
- static S32 PerformRexxCommand( char *commandline, struct AnsweringMachine *am )
- {
- static struct MyRexxCmd
- {
- char *Name;
- S32 (*Func)( char *, struct AnsweringMachine * );
- }
- rexxcmdtab[] =
- {
- "BACKGROUND", RXFunc_Background,
- "FADE", RXFunc_Fade,
- "HANGUP", RXFunc_HangUp,
- "PLAY", RXFunc_Play,
- "RECORD", RXFunc_Record,
- "WAITKEY", RXFunc_WaitKey,
- NULL, NULL
- };
-
- struct MyRexxCmd *cptr;
-
- printf( "PerformRexxCommand( \"%s\" )\n", commandline );
-
- rexx_resultstring[0] = '\0'; /* Resultat löschen */
-
- for (cptr = rexxcmdtab; cptr->Name; cptr++)
- {
- char *s, *d;
- for (s = commandline, d=cptr->Name; *d; s++, d++)
- {
- if(ToUpper( (ULONG)*s ) != *d )
- break;
- }
-
- if (*s <= ' ') /* Kommandoname fertig: das richtige */
- {
- S32 result;
-
- while (*s == ' ') /* Spaces überhüpfen */
- s++;
-
- /* arexxflag = TRUE; */
- result = (*cptr->Func)( s, am ); /* Funktion aufrufen */
- /* arexxflag = FALSE; */
-
- return result;
- }
- }
-
- printf( "Unknown command!\n" );
- return RC_ERROR;
- }
-
-
- /****** ARexx_Init **********************************************************
- *
- * NAME
- * ARexx_Init -- Initialize ARexx
- *
- * SYNOPSIS
- * sigmask = ARexx_Init()
- *
- * BOOL ARexx_Init( VOID );
- *
- * FUNCTION
- * Opens the required libraries (rexxsyslib)
- *
- * INPUTS
- *
- * RESULTS
- *
- * SEE ALSO
- * ARexx_Exit()
- *
- ****************************************************************************/
-
- BOOL ARexx_Init( VOID )
- {
- if (RexxSysBase = OpenLibrary( RXSNAME, 0 ))
- {
- return TRUE;
- }
-
- ARexx_Exit();
- return 0;
- }
-
-
- /****** ARexx_Exit **********************************************************
- *
- * NAME
- * ARexx_Exit -- Close our ARexx port
- *
- * SYNOPSIS
- * ARexx_Exit()
- *
- * VOID ARexx_Exit( VOID );
- *
- * FUNCTION
- * Tries to close down our ARexx port and all associated resources.
- * Will wait until all running scripts have terminated.
- *
- * INPUTS
- *
- * RESULTS
- *
- * SEE ALSO
- * ARexx_Init()
- *
- ****************************************************************************/
-
- VOID ARexx_Exit( VOID )
- {
- if (RexxSysBase != NULL)
- {
- CloseLibrary( RexxSysBase );
- RexxSysBase = NULL;
- }
- }
-
-
- /****** ARexx_HandleMessages ************************************************
- *
- * NAME
- * ARexx_HandleMessages -- Handle ARexx messages
- *
- * SYNOPSIS
- * ARexx_HandleMessages( port, userdata )
- *
- * VOID ARexx_HandleMessages( struct MsgPort *, VOID * );
- *
- * FUNCTION
- * Handles all ARexx messages which are currently waiting on our
- * message port. This function is usually called after the ARexx
- * signal has been received.
- *
- * INPUTS
- * port - Port to get messages from
- * userdata - User data, will be forwarded to all functions
- *
- * RESULTS
- * none
- *
- * SEE ALSO
- *
- ****************************************************************************/
-
- VOID ARexx_HandleMessages( struct ARexxPort *ap )
- {
- struct RexxMsg *msg;
-
- /* printf( "ARexx_HandleMessages( 0x%08lx )\n", ap ); */
-
- if (ap == NULL) /* Sofort zurück falls ARexx nicht läuft */
- return;
-
- while (msg = (struct RexxMsg *)GetMsg( ap->Port ))
- {
- if (msg->rm_Node.mn_Node.ln_Type != NT_REPLYMSG)
- {
- /*
- ** Es ist eine gültige Message und nicht eine Antwort.
- */
- if (IsRexxMsg( msg ))
- {
- /* Sollen wir ein Kommando auführen ? */
- if ((msg->rm_Action & RXCODEMASK) == RXCOMM)
- {
- msg->rm_Result1 = 0;
- msg->rm_Result2 = 0;
-
- if (msg->rm_Result1 = PerformRexxCommand( msg->rm_Args[0], ap->UserData ))
- {
- /* Func returned an error */
- }
- else if((*rexx_resultstring) && (msg->rm_Action & RXFF_RESULT))
- {
- msg->rm_Result2 = (LONG)
- CreateArgstring( rexx_resultstring, (ULONG)strlen( rexx_resultstring ) );
- }
- }
- }
-
- ReplyMsg( &msg->rm_Node );
- }
- else
- {
- /*
- ** Diese Message ist ein reply auf eine Message welche wir
- ** früher mal geschickt haben
- */
- DeleteArgstring( msg->rm_Args[0] );
- #if 0
- if (msg->rm_Stdin)
- Close( msg->rm_Stdin );
- #endif
- DeleteRexxMsg( msg );
- ap->MsgCount--;
- }
- }
- }
-
-
- /****************************************************************************
- ** Eine RexxMessage schicken (Speicher wird von RexxMsgHandler freigegeben)
- ** Parameter: Kommando-String
- */
-
- BOOL
- ARexx_LaunchScript( struct ARexxPort *ap, char *command )
- {
- struct MsgPort *masterport;
-
- if (masterport = FindPort( "REXX" ))
- {
- struct RexxMsg *msg;
-
- if (msg = CreateRexxMsg( ap->Port, MYREXXSUFFIX, ap->Port->mp_Node.ln_Name ))
- {
- if(msg->rm_Args[0] = CreateArgstring( command, (ULONG)strlen( command ) ))
- {
- msg->rm_Action = RXCOMM | RXFF_TOKEN;
- msg->rm_Stdin = Input();
- msg->rm_Stdout = Output();
- PutMsg( masterport, &msg->rm_Node );
- ap->MsgCount++;
-
- return TRUE;
- }
-
- printf( "ARexx_LaunchScript(): CreateArgString failed\n" );
- DeleteRexxMsg( msg );
- }
-
- printf( "ARexx_LaunchScript(): CreateRexxMsg failed\n" );
- }
-
- printf( "ARexx_LaunchScript(): Can't find REXX port\n" );
-
- return FALSE;
- }
-
-
- /*
- ** ARexx-Port erzeugen
- */
- struct ARexxPort *ARexx_CreatePort( char *name, VOID *userdata )
- {
- struct ARexxPort *ap;
-
- if (ap = (struct ARexxPort *)OS_Malloc( sizeof( *ap ) ))
- {
- if (ap->Port = CreatePort( name, 0 ))
- {
- ap->UserData = userdata;
- /* ap->UseCount = 0; */
- }
- else
- {
- OS_Free( ap );
- ap = NULL;
- }
- }
-
- return ap;
- }
-
-
- /*
- ** ARexx-Port freigeben
- */
- VOID ARexx_DeletePort( struct ARexxPort *ap )
- {
- if (ap != NULL)
- {
- if (ap->MsgCount > 0)
- {
- printf( "Port %s: UseCount = %ld, waiting ...\n", ap->Port->mp_Node.ln_Name, ap->MsgCount );
- ARexx_HandleMessages( ap );
- WaitPort( ap->Port );
- }
-
- DeletePort( ap->Port );
- OS_Free( ap );
- }
- }
-